package com.cw.jeeyt.service.impl.system;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.cw.jeeyt.common.Constants;
import com.cw.jeeyt.common.utils.PasswordEncodeUtil;
import com.cw.jeeyt.service.bo.security.SecurityRoleResourceBo;
import com.cw.jeeyt.dao.domain.security.SecurityOrgModel;
import com.cw.jeeyt.dao.domain.security.SecurityRoleModel;
import com.cw.jeeyt.dao.domain.security.SecurityUserModel;
import com.cw.jeeyt.dao.intf.security.SecurityOrgDao;
import com.cw.jeeyt.dao.intf.security.SecurityResourceDao;
import com.cw.jeeyt.dao.intf.security.SecurityRoleDao;
import com.cw.jeeyt.dao.intf.security.SecurityUserDao;
import com.cw.jeeyt.dao.intf.security.SecurityUserRoleDao;
import com.cw.jeeyt.dao.model.security.SecurityOrgDo;
import com.cw.jeeyt.dao.model.security.SecurityResourceDo;
import com.cw.jeeyt.dao.model.security.SecurityRoleResourceDo;
import com.cw.jeeyt.dao.model.security.SecurityUserRoleDo;
import com.cw.jeeyt.service.converter.security.SecurityRoleResourceConverter;
import com.cw.jeeyt.service.intf.security.SecurityRoleResourceService;
import com.cw.jeeyt.service.intf.system.InitializeDataService;
import com.cw.jeeyt.service.intf.system.SystemDictService;
import com.cw.lang.cache.Cache;
import com.cw.lang.common.utils.SequenceTool;

/**
 * 基础数据初始化
 *
 * @author chenw
 */
@Service
public class InitializeDataServiceImpl implements InitializeDataService {
    private static Logger logger = LoggerFactory.getLogger(InitializeDataServiceImpl.class);

    @Autowired
    private SecurityOrgDao securityOrgDao;

    @Autowired
    private SecurityRoleDao securityRoleDao;

    @Autowired
    private SecurityUserDao securityUserDao;

    @Autowired
    private SecurityUserRoleDao userRoleDao;

    @Autowired
    private SecurityResourceDao resourceDao;
    @Autowired
    private SecurityRoleResourceService roleResourceService;
    @Autowired
    private SystemDictService systemDictService;
    @Autowired
    private Cache<String,String> dictCache;

    /**
     * 系统启动时初始化数据
     *
     * @throws Exception
     */
    //@PostConstruct
    @Override
    public void initData() throws Exception {
        if (logger.isInfoEnabled()) {
            logger.info("To init system foundation data...");
        }
        // 初始化组织机构
        initOrgUnit();
        // 初始系统角色
        initRoles();
        // 初始系统用户
        initSystemUser();
        // 初始化角色权限
        initRolePermission();
        //初始化数据字典到redis
        initDictToRedis();
        if (logger.isInfoEnabled()) {
            logger.info("Succeed to init system foundation data...");
        }
    }

    private void initDictToRedis() throws Exception {
        dictCache.set(Constants.DICT_LIST_CACHE, JSON.toJSONString(systemDictService.querySystemDictList()));
    }

    /**
     * 初始化组织机构
     *
     */
    private void initOrgUnit() {
        SecurityOrgDo rootOrgUnit = securityOrgDao.getById(SecurityOrgModel.ROOTID.longValue());
        if (rootOrgUnit == null) {
            rootOrgUnit = new SecurityOrgDo();
            rootOrgUnit.setOrgId(SecurityOrgModel.ROOTID.longValue());
            rootOrgUnit.setOrgName("组织机构");
            rootOrgUnit.setOrgLevelCode("0");
            rootOrgUnit.setOrgType("01");
            rootOrgUnit.setOrgState("01");
            rootOrgUnit.setOrgAddress("");
            rootOrgUnit.setOrgPostCode("");
            rootOrgUnit.setOrgEmail("");
            rootOrgUnit.setOrgPhone("");
            rootOrgUnit.setOrgFax("");
            rootOrgUnit.setOrgSort(0);
            rootOrgUnit.setManagerIds("");
            rootOrgUnit.setManagers("");
            rootOrgUnit.setLeaderIds("");
            rootOrgUnit.setLeaders("");
            rootOrgUnit.setTopOrgIds("");
            rootOrgUnit.setTopOrgs("");
            rootOrgUnit.setOrgComment("");

            try {
                securityOrgDao.insertBySelective(rootOrgUnit);
            } catch (Exception e) {
                logger.error("error add org unit", e);
            }
        }
    }

    /**
     * 初始化角色
     */
    private void initRoles() {
        // 创建一个超级管理员角色，不属于任何公司，拥有所有资源
        SecurityRoleModel ADMINISTRATOR = securityRoleDao.getRoleVoById(SecurityRoleModel.ROLE_ADMIN_ID.longValue());
        if (ADMINISTRATOR == null) {
            ADMINISTRATOR = new SecurityRoleModel();
            ADMINISTRATOR.setComment("系统自动创建：超级管理员角色");
            ADMINISTRATOR.setOrgId(null);
            ADMINISTRATOR.setId(SecurityRoleModel.ROLE_ADMIN_ID.longValue());
            ADMINISTRATOR.setName("超级管理员");
            ADMINISTRATOR.setRoleType("1");
            try {
                securityRoleDao.insert(ADMINISTRATOR);
            } catch (Exception e) {
                logger.error("error when init roles", e);
            }
        }
    }

    /**
     * 初始化系统用户
     */
    private void initSystemUser() {
        SecurityUserModel administrator = securityUserDao.getUserVoById(SecurityUserModel.ADMINISTRATOR_ID.longValue());
        if (administrator == null) {
            administrator = new SecurityUserModel();
            administrator.setId(SecurityUserModel.ADMINISTRATOR_ID.longValue());
            administrator.setAccount(SecurityUserModel.ADMINISTRATOR_ACCOUNT);
            administrator.setDefaultOrgId(SecurityOrgModel.ROOTID.longValue());
            administrator.setEmail("");
            administrator.setComment("");
            administrator.setMobile("");
            administrator.setPosition("");
            administrator.setPassword(PasswordEncodeUtil.encode("admin"));
            administrator.setSex("1");
            administrator.setTelephone("");
            administrator.setUsername("超级管理员");
            administrator.setUserState(true);
            try {
                securityUserDao.insert(administrator);
                String id = SequenceTool.nextId();
                SecurityUserRoleDo userRole = new SecurityUserRoleDo();
                userRole.setId(SequenceTool.nextId());
                userRole.setUserId(SecurityUserModel.ADMINISTRATOR_ID.longValue());
                userRole.setRoleId(SecurityRoleModel.ROLE_ADMIN_ID.longValue());
                userRoleDao.insert(userRole);
            } catch (Exception e) {
                logger.error("error when init system user", e);
            }
        }
    }

    /**
     * 初始化角色权限
     */
    private void initRolePermission() {
        try {
            List<SecurityRoleResourceBo> oldList = roleResourceService.queryRoleResourceByRoleId(
                SecurityRoleModel.ROLE_ADMIN_ID.longValue());
            // 获取所有操作资源
            List<SecurityResourceDo> resourceList = resourceDao.queryResourceList();
            // 获取到需要移除的关联
            List<SecurityRoleResourceBo> forRemove = new ArrayList<>();
            outer:
            for (SecurityRoleResourceBo securityRoleResourceBo : oldList) {
                SecurityRoleResourceDo securityRoleResource = SecurityRoleResourceConverter.bo2Do(
                    securityRoleResourceBo);
                for (SecurityResourceDo resource : resourceList) {
                    if (securityRoleResource.getResId()
                        .equals(resource.getId())) {
                        continue outer;
                    }
                }
                forRemove.add(securityRoleResourceBo);
            }

            // 获取待新增的roleOperator
            List<Long> list = new ArrayList<Long>();
            outer:
            for (SecurityResourceDo resource : resourceList) {
                for (SecurityRoleResourceBo securityRoleResourceBo : oldList) {
                    SecurityRoleResourceDo securityRoleResource = SecurityRoleResourceConverter.bo2Do(
                        securityRoleResourceBo);
                    if (resource.getId()
                        .equals(securityRoleResource.getResId())) {
                        continue outer;
                    }
                }
                list.add(resource.getId());
            }

            // 执行删除
            for (SecurityRoleResourceBo securityRoleResource : forRemove) {
                roleResourceService.delete(securityRoleResource);
            }

            // 处理新增
            if (list != null && !list.isEmpty()) {
                roleResourceService.insertRoleResource(SecurityRoleModel.ROLE_ADMIN_ID.longValue(), list);
            }
        } catch (Exception e) {
            logger.error("error when init admin role permission", e);
        }
    }
}
